
using System;
using System.IO;
using NUnit.Framework;

using Subsync.Core.Subversion;

namespace Subsync.Test.UnitTests
{
	
	/// <summary>
	/// In this Unit Test, we will test the subversion commands in 
	/// Core/Subversion.
	/// </summary>
	[TestFixture()]
	public class SubversionCommands
	{
		string testing_folder;
		string working_copy;
		string repos_path;
		string repos_url;
		string[] url_sp;
		string lock_file;
		string newFileName;
		
		public SubversionCommands() {
			testing_folder = Path.Combine(Directory.GetCurrentDirectory(),"unit_test");
			working_copy = Path.Combine(testing_folder,"working_copy");
			repos_path = Path.Combine(testing_folder,"_repos");
			repos_url = "http://subsynct.googlecode.com/svn/trunk/dev";
			newFileName = "a.txt";
			url_sp = repos_url.Split('/');
			Directory.Delete(testing_folder);
			Directory.CreateDirectory(testing_folder);
			Directory.CreateDirectory(working_copy);
		}
		
		/// <summary>
		/// create a new repository and check if the right files/dir is created.
		/// </summary>
		[Test()]
		public void SVNAdminCreate()
		{	
			//create the repository
			new SVNAdminCreate(repos_path).Execute();
		
			//check for the repository creation
			
			//check for conf folder
			string conf_folder = Path.Combine(repos_path,"conf");
			Assert.IsTrue(Directory.Exists(conf_folder));
			
			//check for conf/svnserve.conf
			Assert.IsTrue(File.Exists(Path.Combine(conf_folder,"svnserve.conf")));
			
			//check for db folder
			string db_folder = Path.Combine(repos_path,"db");
			Assert.IsTrue(Directory.Exists(db_folder));
			
			//check for db/uuid
			Assert.IsTrue(File.Exists(Path.Combine(db_folder,"uuid")));
			
			//check for hooks folder
			string hooks_folder = Path.Combine(repos_path,"hooks");
			Assert.IsTrue(Directory.Exists(hooks_folder));
			
			//check for locks folder
			string locks_holder = Path.Combine(repos_path,"locks");
			Assert.IsTrue(Directory.Exists(locks_holder));
		}
		
		/// <summary>
		/// checks out a new repository and check if the right folder is created.
		/// </summary>
		[Test()]
		public void SVNCheckout()
		{	
			//checkout the repository
			new SVNCheckout(repos_url).Execute();
			
			string checkout_folder = Path.Combine(working_copy, url_sp[url_sp.Length-1]);
			
			//check if folder exists		
			Assert.IsTrue(Directory.Exists(checkout_folder));
		}
		
		/// <summary>
		/// adds a file to the repository and checks if its done correctly
		/// </summary>
		[Test()]
		public void SVNAdd()
		{	
			//combine the new filename with the path
			string newFilePath = Path.Combine(testing_folder, newFileName);					
			
			// Create the file and write to it.
			// DANGER: File.Create will overwrite the file if it already exists. 		
            File.Create(newFilePath);
			File.WriteAllText(newFilePath, "Test Content");			
			
			//Move the file to working_copy/dev for the repos_url in this test
			string destinationFilePath = Path.Combine(Path.Combine(working_copy, url_sp[url_sp.Length-1]),newFileName);
			File.Move(newFilePath, destinationFilePath);
						
			//add the file to repository 
			new SVNAdd(destinationFilePath).Execute();
			
			//commit the working copy	
			new SVNCommit(working_copy).Execute();	
			
			//update the working copy	
			new SVNUpdate(working_copy).Execute();				
			
			//check that file exists
			Assert.IsTrue(File.Exists(destinationFilePath));
			
		}
		
		/// <summary>
		/// removes a file from the repository and checks if its done correctly
		/// </summary>
		[Test()]
		public void SVNRemove()
		{	
			//path of file to remove
			//Move the file to working_copy/dev for the repos_url in this test
			string destinationFilePath = Path.Combine(Path.Combine(working_copy, url_sp[url_sp.Length-1]),newFileName);
						
			// Remove the file	
			if (File.Exists(destinationFilePath))
			{
			new SVNRemove(destinationFilePath).Execute();
			}
			
			//commit the working copy	
			new SVNCommit(working_copy).Execute();	
			
			//update the working copy	
			new SVNUpdate(working_copy).Execute();				
			
			//check that file exists
			Assert.IsTrue(!File.Exists(destinationFilePath));
			
		}
		
		/// <summary>
		/// makes new directory
		/// </summary>
		[Test()]
		public void SVNMkdir()
		{	
			//url of new directory
			string[] mkdir = {string.Concat(repos_url, "newdir")};				
			// Make new directory	
			
			new SVNMkdir(mkdir, "Making new directory").Execute();
			
			
			//commit the working copy	
			new SVNCommit(working_copy).Execute();	
			
			//update the working copy	
			new SVNUpdate(working_copy).Execute();				
			
			//check that directory exists
			Assert.IsTrue(Directory.Exists(Path.Combine (checkout_folder, "newdir")));
					}
			              
	    [ExpectedException( typeof(SVNObjectLocked) )]
		[Test()]
		public void SVNLock ()
		{
			//create a file
			lock_file = Path.Combine (working_copy, "lockme.txt");
			TextWriter lockme = new StreamWriter (lock_file);
			lockme.WriteLine ("please lock me, i've been bad.");
			lockme.Close ();
			
			//svn add
			new SVNAdd (lock_file).Execute();
		
			//commit it
			new SVNCommit(working_copy).Execute();
			
			//lock it
			new SVNLock(lock_file,"").Execute();
			
			//try deleting it.
			new SVNRemove(lock_file).Execute();
			
			//commit it
			new SVNCommit(working_copy).Execute();
			
		}
		
		[Test()]
		public void SVNUnlock()
		{
			//unlock file
            new SVNUnlock(lock_file).Execute();
			
			//try deleting it.
			new SVNRemove(lock_file).Execute();
			
			//commit it
			new SVNCommit(working_copy).Execute();
		}
		
		[Test()]
		public void SVNPropSet ()
		{
			//create a file
			lock_file = Path.Combine (working_copy, "lockme.txt");
			TextWriter lockme = new StreamWriter (lock_file);
			lockme.WriteLine ("please lock me, i've been bad.");
			lockme.Close ();
			
			//set ignore
			//new SVNPropSet (lock_file, "svn:ignore", "");
			
			//do a status check
			
			
		}
		
		/// <summary>
		/// performs an SVN import
		/// </summary>
		[Test()]
		public void SVNImport()
		{
			
		}

		/// <summary>
		/// moves the repository
		/// </summary>
		[Test()]
		public void SVNMove()
		{	
			//Create folder to test SVNMove
			string moved_copy = Path.Combine(testing_folder,"moved_copy");
			Directory.Delete(moved_copy);
			Directory.CreateDirectory(moved_copy);
			
			//checkout the repository
			new SVNMove(working_copy, moved_copy).Execute();
			
			//commit the working copy	
			new SVNCommit(moved_copy).Execute();	
			
			//update the working copy	
			new SVNUpdate(moved_copy).Execute();	
						
			//check if working_copy directory is empty
			Assert.IsTrue(Directory.GetFiles(working_copy).Length == 0);
		}
		
		/// <summary>
		/// reverts to revision 0 and checks if the working_copy is empty
		/// </summary>
		[Test()]
		public void SVNRevert()
		{	
			
			string[] revertpaths = {working_copy};
			//checkout the repository"
			new SVNRevert(revertpaths).Execute();
						
			//check if directory is empty
			Assert.IsTrue(Directory.GetFiles(working_copy).Length == 0);
		}
	}
}